package com.inspur.edp.formserver.vmmanager.validate;

import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.GspViewModelElement;
import com.inspur.edp.formserver.viewmodel.GspViewObject;
import com.inspur.edp.formserver.viewmodel.action.ViewModelAction;
import com.inspur.edp.formserver.viewmodel.action.ViewModelActionType;
import com.inspur.edp.formserver.viewmodel.collection.VMActionCollection;
import com.inspur.edp.formserver.viewmodel.common.ViewModelMapping;
import com.inspur.edp.formserver.vmmanager.exception.VmManagerException;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

public class MultiSourceValidate
{
	private String errorCode = "vo多源检查";
	private java.util.HashMap<String, String> sourceDic = new java.util.HashMap<String, String>();

	/** 
	 临时兼容-仅单源vo可编译
	 
	 @param vm
	 @return 
	*/
	public final boolean validate(GspViewModel vm)
	{
		if (vm==null)
		{
			return false;
		}
		return validateFromMultiSource(vm) && validateImportMoreThanOneTime(vm);
	}

	/** 
	 多be源
	 
	 @param vm
	 @return 
	*/
	private boolean validateFromMultiSource(GspViewModel vm)
	{
		String beId = vm.getMapping().getTargetMetadataId();
		// 节点
		validateObject(vm.getMainObject(), beId);
		// 操作
		validateActions(vm.getActions(), beId);
		return true;
	}

	private void validateActions(VMActionCollection vmActions, String beID)
	{
		if (vmActions != null && vmActions.size() > 0)
		{
			for (ViewModelAction action : vmActions)
			{
				if (action.getType() == ViewModelActionType.BEAction)
				{
					if (!action.getMapping().getTargetMetadataId().equals(beID))
					{
						throw new VmManagerException("",errorCode, "操作"+action.getName()+"来源自其它业务实体，暂不支持[保存并同步]及[编译]。",null,
								ExceptionLevel.Error,false);
					}
				}
			}
		}
	}

	private void validateObject(GspViewObject vo, String beID)
	{
		// 当前对象
		if (!vo.getMapping().getTargetMetadataId().equals(beID))
		{
			throw new VmManagerException("",errorCode, "对象'"+vo.getName()+"'来源自其它业务实体，暂不支持[保存并同步]及[编译]。",null,ExceptionLevel.Error,false);
		}

		// 字段
		if (vo.getContainElements() != null && vo.getContainElements().size() > 0)
		{
			for (IGspCommonField ele : vo.getContainElements())
			{
				if (!((GspViewModelElement)ele).getMapping().getTargetMetadataId().equals(beID))
				{
					if (((GspViewModelElement)ele).getIsVirtualViewElement())
					{
						continue;
					}
					throw new VmManagerException("",errorCode, "对象"+vo.getName()+"中的字段"+ele.getName()+"来源自其它业务实体，暂不支持[保存并同步]及[编译]。",null,ExceptionLevel.Error,false);
				}
			}
		}

		// 子节点
		if (vo.getContainChildObjects() != null && vo.getContainChildObjects().size() > 0)
		{
			for (IGspCommonObject childObject : vo.getContainChildObjects())
			{
				validateObject((GspViewObject) childObject, beID);
			}
		}
	}

	/** 
	 单be源引入多次
	 
	 @param vm
	 @return 
	*/
	private boolean validateImportMoreThanOneTime(GspViewModel vm)
	{
		sourceDic.clear();
		GspMetadata metadata = SpringBeanUtils.getBean(RefCommonService.class).getRefMetadata(vm.getMapping().getTargetMetadataId());
		if (metadata == null || !(metadata.getContent() instanceof GspBusinessEntity))
		{
			throw new VmManagerException("",errorCode, "无法加载当前vo映射的业务实体，metadataID='{vm.Mapping.TargetMetadataId}'",null,ExceptionLevel.Error,false);
		}

		checkMapping(vm.getMapping(), "当前视图对象");

		// 对象
		validateImportObjectOneTime(vm.getMainObject(), (GspBusinessEntity) metadata.getContent());

		return true;
	}

	private void validateImportObjectOneTime(GspViewObject vo, GspBusinessEntity be)
	{
		// 当前对象
		checkMapping(vo.getMapping(), "对象{vo.Name}");



		GspBizEntityObject currentBizObj = (GspBizEntityObject) be.getAllObjectList().stream().filter(item->item.getID().equals(vo.getMapping().getTargetObjId())).findFirst().orElse(null);//.FirstOrDefault(item => String.equals(item.ID, vo.getMapping().getTargetObjId()));
		if (currentBizObj == null)
		{
			throw new VmManagerException("",errorCode, "对象{vo.Name}在业务实体中无对应节点，暂不支持[保存并同步]及[编译]。。",null,ExceptionLevel.Error,false);
		}

		IGspCommonObject tempVar = vo.getParentObject();

		GspViewObject parentObj = (GspViewObject)((tempVar instanceof GspViewObject) ? tempVar : null);
		if (parentObj != null)
		{
			if (currentBizObj.getParentObject().getID() != parentObj.getMapping().getTargetObjId())
			{
				throw new VmManagerException("",errorCode, "对象{vo.Name}结构与业务实体不一致，暂不支持[保存并同步]及[编译]。",null,ExceptionLevel.Error,false);
			}
		}

		// 字段
		if (vo.getContainElements() != null && vo.getContainElements().size() > 0)
		{
			for (IGspCommonField ele : vo.getContainElements())
			{
				if (((GspViewModelElement)ele).getIsVirtualViewElement())
				{
					continue;
				}
				checkMapping(((GspViewModelElement)ele).getMapping(), "对象'{vo.Name}'中的字段'{ele.Name}'");

				if (currentBizObj.findElement(((GspViewModelElement)ele).getMapping().getTargetObjId())==null)
				{
					throw new VmManagerException("",errorCode, "对象'{vo.Name}'中的字段'{ele.Name}'在业务实体中无对应节点，暂不支持[保存并同步]及[编译]。。",null,ExceptionLevel.Error,false);
				}
			}
		}

		// 子节点
		if (vo.getContainChildObjects() != null && vo.getContainChildObjects().size() > 0)
		{
			for (IGspCommonObject childObject : vo.getContainChildObjects())
			{
				validateImportObjectOneTime((GspViewObject) childObject, be);
			}
		}
	}

	private void checkMapping(ViewModelMapping mapping, String errorMessage)
	{
		String targetObjId = mapping.getTargetObjId();
		if (sourceDic.containsKey(targetObjId))
		{
			throw new VmManagerException("",errorCode, String.format(errorMessage + "由业务实体引入的次数多于1次，暂不支持[保存并同步]及[编译]。"),null,ExceptionLevel.Error,false);
		}
		else
		{
			sourceDic.put(targetObjId, null);
		}
	}
}